package monitoring;
import java.util.concurrent.LinkedBlockingQueue;

import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.hibernate.SessionFactory;
import org.jboss.ejb3.annotation.*;

import store.hibernate.Event;
import store.hibernate.RawData;

import monitoring.sla.MonitoringEvent;
import monitoring.ManagerServiceMBean;
import monitoring.event.LazyInsertEvent;
import monitoring.event.analysis.DataAnalysis;
import monitoring.logdata.LazyInsertLogData;
import monitoring.rawdata.LazyInsertRawData;
import monitoring.rawdata.LazyRemoveRawData;
import monitoring.rawdata.LoadingBackupQueue;
import monitoring.rawdata.RawDataProcessing;
import monitoring.rawdata.analysis.DataObject;
import monitoring.rawdata.analysis.DecomposingPacket;
import monitoring.sla.MonitoringComponent;
import monitoring.sla.latency.MonitoringLatency;
import monitoring.sla.parser.slang.SlangBean;
import monitoring.sla.pattern.MonitoringPattern;
import monitoring.sla.throughput.MonitoringThroughput;
import monitoring.udpdata.UDPServer;
import monitoring.utility.StaticFields;


@Service(objectName = "servicePOJO:service=ManagerService") 
@Management(ManagerServiceMBean.class)
@Depends("jboss.jca:name=MySqlDS,service=DataSourceBinding")

public class ManagerService implements ManagerServiceMBean {  


	private UDPServer us;
	private SessionFactory  factory;


	public void start() throws Exception{
		
	}

	// Lifecycle methods 
	public void create() throws Exception { 
		try {
			InitialContext ctx = new InitialContext(); 
			factory = (SessionFactory)ctx.lookup("java:/hibernate/SessionFactory");
			
			//SERVIZIO DI RIMOZIONE PERSISTENTE DI RAWDATA
			LinkedBlockingQueue<byte[]> rawDataToRemove = new LinkedBlockingQueue<byte[]>();
			new LazyRemoveRawData(rawDataToRemove, factory).start();
			
			//SERVIZIO DI DISTRIBUZIONE DEI DATI
			LinkedBlockingQueue<RawData> rawData = new LinkedBlockingQueue<RawData>();
			RawDataProcessing rdp = new RawDataProcessing(rawData, rawDataToRemove, new DecomposingPacket());

			
			MonitoringComponent mc,mc1;
	        mc1 = mc = new MonitoringPattern();
	        mc1 = mc1.setNext(new MonitoringThroughput());
	        mc1 = mc1.setNext(new MonitoringLatency());
	        String slaLanguageInUse=StaticFields.SLANG_LANGUAGE;
	        
	        SlangBean.addSlaLanguage(slaLanguageInUse, new SlangBean());
	        
			//SERVIZIO DI INDIVIDUZIONE DELLE VIOLAZIONI DEGLI EVENTI
			LinkedBlockingQueue<Event> eventData = new LinkedBlockingQueue<Event>();
			new MonitoringEvent(eventData, factory, mc, slaLanguageInUse).start();
			
			//SERVIZIO DI INSERIMENTO PERSISTENTE DI EVENTI
			LinkedBlockingQueue<DataObject> rawDataToEvent = new LinkedBlockingQueue<DataObject>();
			rdp.addQueue(rawDataToEvent);
			new LazyInsertEvent(rawDataToEvent, rawDataToRemove, eventData, new DataAnalysis(), factory).start();

		
			//SERVIZIO DI INSERIMENTO PERSISTENTE DI LOGDATA
		/*	LinkedBlockingQueue<DataObject> rawDataToLogData = new LinkedBlockingQueue<DataObject>();
			rdp.addQueue(rawDataToLogData);
			new LazyInsertLogData(rawDataToLogData, factory).start();
		*/
			//AVVIO SERVIZIO DI DISTRIBUZIONE DEI DATI
			rdp.start();

			//SERVIZIO DI INSERIMENTO PERSISTENTE DI RAWDATA
			LinkedBlockingQueue<RawData> udpPacketToRawData = new LinkedBlockingQueue<RawData>();
			new LazyInsertRawData(udpPacketToRawData, rawData, factory).start();
	
			//SERVIZIO DI LOADING DAL DISCO IN MEMORIA DI RAWDATA
			new LoadingBackupQueue(rawData, factory);

			//SERVIZIO DI RICEZIONE DI PACCHETTI UDP
			us=new UDPServer(udpPacketToRawData);
			us.start();
		} catch (NamingException e) {
			e.printStackTrace();
		}
	} 

	public void destroy() {    
		us.closeSocket();
		factory = null;
	}

} 

